package com.wan37.logic.handler.message;

import com.sun.org.apache.bcel.internal.generic.IF_ACMPEQ;
import com.wan37.logic.component.Worker;
import com.wan37.logic.domain.Result;
import com.wan37.logic.domain.vo.*;
import com.wan37.logic.fighting.hand.Fighting;
import com.wan37.logic.fighting.hand.PVEManager;
import com.wan37.logic.fighting.hand.PVPManager;
import com.wan37.logic.global.HandlerManager;
import com.wan37.logic.global.reference.SpringContextHolder;
import com.wan37.logic.handler.MsgHandler;
import com.wan37.logic.service.cache.*;
import com.wan37.logic.utils.RouteUtils;
import com.wan37.protobuf.constant.*;
import com.wan37.protobuf.message.client2server.game.Game;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @author : luoyong
 * @date : 2020-06-03 09:39
 **/
public class CGameAttackHandler extends MsgHandler {

    private static final Logger logger = LoggerFactory.getLogger("CGameAttackHandler.class");

    private Fighting fighting;
    private RoleServiceCache roleServiceCache;
    private SceneServiceCache sceneServiceCache;
    private RouteUtils routeUtils;
    private SkillServiceCache skillServiceCache;
    private PVPManager pvpManager;
    private PVEManager pveManager;
    private MonsterServiceCache monsterServiceCache;

    /**
     * MsgHandler构造函数
     *
     * @param messageVO
     */
    public CGameAttackHandler(MessageVO messageVO) {
        super(messageVO);
        this.roleServiceCache = SpringContextHolder.getBean("roleServiceCache");
        this.sceneServiceCache = SpringContextHolder.getBean("sceneServiceCache");
        this.routeUtils = SpringContextHolder.getBean("routeUtils");
        this.skillServiceCache = SpringContextHolder.getBean("skillServiceCache");
        this.pveManager = SpringContextHolder.getBean("pVEManager");
        this.pvpManager = SpringContextHolder.getBean("pVPManager");
        this.monsterServiceCache = SpringContextHolder.getBean("monsterServiceCache");
    }

    @Override
    public void execute(Worker worker) throws Exception {
        Game.CGameAttack cGameAttack = (Game.CGameAttack) messageVO.getMessage();
        String sceneId = sceneServiceCache.sceneNameToIdMap.get(cGameAttack.getSceneName());
        String skillId = cGameAttack.getSkillId();
        int sender = 0;
        int receiver = 0;
        if (sceneId == null) {
            routeUtils.sendGameAttackResponse(Common.GAME_ATTACK_ERROR, "场景不存在！",
                    messageVO.getUserId(), cGameAttack.getSenderId(), messageVO.getNetId(), skillId);
            return;
        }

        Map<String, AllRoleVO> allRoleVOMap = sceneServiceCache.getSceneServiceMap().get(sceneId).getAllRoleVOMap();

        Result result = null;

        if (roleServiceCache.getRoleServiceMap().containsKey(cGameAttack.getSenderId())) {
            Map<String, SkillVO> skillVOMap = roleServiceCache.getRoleServiceMap()
                    .get(cGameAttack.getSenderId()).getSkillVOMap();
            /**
             * 校验技能是否可以释放
             */
            if (skillVOMap.containsKey(skillId)) {
                SkillVO skillVO = skillVOMap.get(skillId);
                if ((skillVO.getUseTime() + skillVO.getCD() * 1000) > System.currentTimeMillis()) {
                    Set<String> userIdSet = new HashSet<>();
                    userIdSet.add(messageVO.getUserId());
                    routeUtils.sendAttackBroadcastResponse(CommonFighting.ATTACK_ERROR_SKILL_CD, userIdSet,
                            cGameAttack.getSenderId(), null, skillId, null);
                    return;
                }
            }

            if (allRoleVOMap.containsKey(cGameAttack.getReceiverId())) {
                this.fighting = SpringContextHolder.getBean("playerAttackMonster");
                sender = AllRoleLabel.ROLE;
                receiver = AllRoleLabel.MONSTER;
            } else if (roleServiceCache.getRoleServiceMap().containsKey(cGameAttack.getReceiverId())) {
                this.fighting = SpringContextHolder.getBean("playerAttackPlayer");
                sender = AllRoleLabel.ROLE;
                receiver = AllRoleLabel.ROLE;
            }
        } else if (allRoleVOMap.containsKey(cGameAttack.getSenderId())) {
            if (!monsterServiceCache.isBossAttack(sceneId, cGameAttack.getSenderId(), messageVO.getUserId())){
                return;
            }
            if (roleServiceCache.getRoleServiceMap().containsKey(cGameAttack.getReceiverId())) {
                this.fighting = SpringContextHolder.getBean("monsterAttackPlayer");
                sender = AllRoleLabel.MONSTER;
                receiver = AllRoleLabel.ROLE;
            }
        }

        if (this.fighting != null) {
            List<String> allRoleVOIdList = new ArrayList<>();
            allRoleVOIdList.add(cGameAttack.getReceiverId());
            //进行战斗技能处理
            result = this.fighting.start(new FightingVO(skillId,
                    messageVO.getUserId(), cGameAttack.getSenderId(), allRoleVOIdList, sceneId));
            /**
             * 获取战斗后数值可能改变的对象，进行全地图广播，让其他玩家和自己看到变化
             */
            if (result instanceof SuccessFightingResult) {
                SuccessFightingResult successFightingResult = (SuccessFightingResult) result;
                Map<String, Map<String, Long>> allRoleVONumberMap = successFightingResult.getAllRoleVONumberMap();
                if (sender == AllRoleLabel.MONSTER || receiver == AllRoleLabel.MONSTER) {
                    pveManager.responseClient(allRoleVONumberMap, successFightingResult.getCode(), sceneId,
                            allRoleVOIdList, skillId, cGameAttack.getSenderId(), sender, receiver, messageVO);
                } else {
                    if (skillServiceCache.getSkillServiceMap().get(skillId)
                            .getSkillVO().getLabel().startsWith(SkillLabel.FRIEND, 1)) {
                        pveManager.responseClient(allRoleVONumberMap, successFightingResult.getCode(), sceneId,
                                allRoleVOIdList, skillId, cGameAttack.getSenderId(), sender, receiver, messageVO);
                    } else {
                        pvpManager.responseClient(allRoleVONumberMap, successFightingResult.getCode(), sceneId,
                                allRoleVOIdList, skillId, cGameAttack.getSenderId(), sender, receiver, messageVO);
                    }
                }

            } else {
                if (result.getCode() == CommonFighting.ATTACK_ERROR_IS_DIE){
                    routeUtils.sendGameAttackResponse(Common.GAME_ATTACK_ERROR, "角色已死亡，无法攻击！",
                            messageVO.getUserId(), cGameAttack.getSenderId(), messageVO.getNetId(), skillId);

                }else {
                    routeUtils.sendAttackBroadcastResponse(result.getCode(), sceneServiceCache.getSceneServiceMap()
                            .get(sceneId).getUserIdSet(), cGameAttack.getSenderId(), allRoleVOIdList, skillId, null);
                }
            }
            logger.info("角色: " + cGameAttack.getSenderId() + " 使用技能 " + skillId + " 攻击了 " + cGameAttack.getReceiverId());
        } else {
            Set<String> userIdSet = new HashSet<>();
            userIdSet.add(messageVO.getUserId());
            routeUtils.sendAttackBroadcastResponse(CommonFighting.ATTACK_ERROR, userIdSet,
                    cGameAttack.getSenderId(), null, skillId, null);
        }
    }
}
